package br.ufmg.dcc.vod.remoteworkers.registry;
import java.rmi.AlreadyBoundException;
import java.rmi.NotBoundException;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class ServiceRegistry<T extends Remote> {

	private final Registry rmiRegistry;
	private final Map<String, T> localRegistry;

	public ServiceRegistry(int port) throws RemoteException {
		this.rmiRegistry = LocateRegistry.createRegistry(port);
		this.localRegistry = new HashMap<String, T>();
	}
	
	public void bindProcessor(String name, T t) throws RemoteException, AlreadyBoundException {
		rmiRegistry.bind(name, t);
		localRegistry.put(name, t);
	}

	public T unbindProcessor(String name) throws RemoteException, NotBoundException {
		rmiRegistry.unbind(name);
		T t = localRegistry.remove(name);
		UnicastRemoteObject.unexportObject(t, false);
		return t;
	}
	
	public Collection<T> stopService() throws RemoteException, NotBoundException {
		List<T> returnValue = new ArrayList<T>();
		
		Set<String> set = new HashSet<String>(localRegistry.keySet());
		for (String s : set) {
			T t = unbindProcessor(s);
			returnValue.add(t);
		}
		
		return returnValue;
	}
}